package monitor

import (
	"image"
	"image/draw"
	"image/png"
	"net/http"
	"strconv"
	"sync"
	"sync/atomic"
	"time"
)

var (
	grafanaWeight           = 600
	grafanaHeight           = 350
	grafanaHeightAndPadding = 370
)

func grafanaDashboard(httpClient *http.Client, dashboardURL string, panels int, orgID int, hours int) image.Image {
	height := panels * grafanaHeightAndPadding

	dashboardImg := image.NewRGBA(image.Rectangle{image.Point{0, 0}, image.Point{grafanaWeight, height}})

	var sg sync.WaitGroup
	sg.Add(panels)

	var k uint32
	for i := 1; i <= panels; i++ {
		i := i
		go func() {
			defer sg.Done()
			img, err := getGrafanaImage(httpClient, dashboardURL, orgID, i, hours)
			if err == nil {
				kk := atomic.AddUint32(&k, 1) - 1
				r := image.Rectangle{
					Min: image.Point{X: 0, Y: grafanaHeightAndPadding * int(kk)},
					Max: image.Point{X: grafanaWeight, Y: grafanaHeightAndPadding * (int(kk) + 1)},
				}
				draw.Draw(dashboardImg, r, img, image.Point{0, 0}, draw.Src)
			}
		}()

	}

	sg.Wait()

	if atomic.LoadUint32(&k) == 0 {
		return nil
	}

	result := image.NewRGBA(image.Rectangle{image.Point{0, 0}, image.Point{grafanaWeight, int(k) * grafanaHeightAndPadding}})
	r := image.Rectangle{
		Min: image.Point{X: 0, Y: 0},
		Max: image.Point{X: grafanaWeight, Y: grafanaHeightAndPadding * (int(k) + 1)},
	}
	draw.Draw(result, r, dashboardImg, image.Point{0, 0}, draw.Src)

	return result
}

func getGrafanaImage(httpClient *http.Client, dashboard string, orgID, panelID int, hours int) (image.Image, error) {
	to := int(time.Now().UnixNano() / 1e6)
	from := to - hours*3600*1000

	var url = dashboard + "?orgId=" + strconv.Itoa(orgID) + "&panelId=" + strconv.Itoa(panelID) + "&from=" + strconv.Itoa(from) + "&to=" + strconv.Itoa(to) + "&width=" + strconv.Itoa(grafanaWeight) + "&height=" + strconv.Itoa(grafanaHeight) + "&tz=UTC%2B08%3A00"

	resp, err := httpClient.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	return png.Decode(resp.Body)

}
